﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using TheVerge.Base.Platform;
using TheVerge.Base;
using System.Net;
using System.Text.RegularExpressions;

namespace TheVerge.Base.Models
{
    public class VMComment : AVM
    {
        private Comment _BackingComment;
        private List<VMComment> _replies;


        public long ArticleId
        {
            get { return GetValue(() => ArticleId); }
            private set { SetValue(value, () => ArticleId); }
        }

        public bool IsRepliesVisible
        {
            get { 
                if(Replies.Count() > 0)
                    return GetValue(() => IsRepliesVisible);

                //-- If we don't have any comments, then replies are always visible.
                //This is because if we hide 0 replies, it'd appear as if this comment
                //has replies, which it doesn't. It sounds a little weird, but just think about it :)
                return true; 
                }
            set {
                foreach (var c in Replies)
                {
                    c.IsVisible = value;
                    c.IsRepliesVisible = value;
                }
                SetValue(value, () => IsRepliesVisible);
            }
        }

        public bool IsVisible
        {
            get { return GetValue(() => IsVisible); }
            set { SetValue(value, () => IsVisible); }
        }

        public string Body { get { return FormatBody(_BackingComment.Body); } }

        public int NestingDepth
        {
            get { return GetValue(() => NestingDepth); }
            private set { SetValue(value, () => NestingDepth); }
        }

        public IEnumerable<VMComment> Replies
        {
            get { return _replies; }
        }

        public DateTime CreatedOn { get { return _BackingComment.CreatedOn; } }
        public string Title { get { return _BackingComment.Title; } }
        public string UserName { get { return _BackingComment.UserName; } }

        public VMComment(long articleId, Comment comment)
        {
            _BackingComment = comment;

            ArticleId = articleId;
            //-- By default a comment is visible. So instead of iterating over all of the children
            // we can just manually set the IsRepliesVisible to true. The IsVisible property of the
            // children will be set when calling GenerateReplies.
            SetValue(true, () => IsRepliesVisible); 
            IsVisible = true;
            NestingDepth = GetNestingDepth(comment);
            _replies = GenerateReplies(articleId, comment);
        }

        private static string FormatBody(string body)
        {
            body = Factory.HttpUtility.HtmlDecode(body);
            //body = body.Replace(@"<p>", string.Empty).Replace(@"</p>", string.Empty);

            //TODO: Rip out <strong> or any other HTML esce type elements. 
            return Regex.Replace(body, @"<[^>]*>", String.Empty);
        }

        private static List<VMComment> GenerateReplies(long articleId, Comment comment)
        {
            var replies = new List<VMComment>();

            foreach (var reply in comment.Replies)
            {
                replies.Add(new VMComment(articleId, reply));
            }

            return replies;
        }
        
        private static int GetNestingDepth(Comment c)
        {
            var depth = 0;
            while (c.Parent != null)
            {
                depth++;
                c = c.Parent;
            }

            return depth;
        }
    }
}